﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Xc.DataAccess.Core.Extensions
{
    /// <summary>
    /// 字节码扩展
    /// </summary>
    public static class ByteExtension
    {
        /// <summary>
        /// 转换为字节码
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static byte[] ToHex(this string content)
        {
            List<byte> vs=new List<byte>();
            for (int i = 0; i < content.Length; i += 2)
            {
                var text = content.Substring(i, 2);
                vs.Add( Convert.ToByte(text, 16));
            }
            return vs.ToArray();
        }
        /// <summary>
        /// 转换位字节码
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string ToHex(this byte[] content)
        {
            if (content==null)
            {
                return null;
            }
            List<string> vs = new List<string>();
            foreach (var item in content)
            {
                vs.Add(item.ToString("X2"));
            }
            return string.Join("",vs.ToArray());
        }
        /// <summary>
        /// 转换位时间格式
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string ToDateTime(this byte[] content)
        {
            var dt = content.ToHex();
           return "20"+dt.Substring(0, 2) + "/" + dt.Substring(2, 2) + "/" + dt.Substring(4, 2) + " " + dt.Substring(6, 2) + ":" + dt.Substring(8, 2) + ":" + dt.Substring(10, 2);
        }
        /// <summary>
        /// 转换为无符号16位
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static ushort ToUInt16BigEndian(this byte[] content)
        {
            return BitConverter.ToUInt16(content.Reverse().ToArray(),0);
        }
        /// <summary>
        /// 转换为无符号16位
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static byte[] FromUInt16BigEndian(this ushort value)
        {
            return BitConverter.GetBytes(value).Reverse().ToArray();
        }
        /// <summary>
        /// 转换为无符号16位
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static byte[] FromUInt16LittleEndian(this ushort value)
        {
            return BitConverter.GetBytes(value).ToArray();
        }
        /// <summary>
        /// 转换为无符号32位
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static byte[] FromUInt32LittleEndian(this uint value)
        {
            return BitConverter.GetBytes(value).ToArray();
        }
        /// <summary>
        /// 将deciaml 值转换为 字节码
        /// </summary>
        /// <param name="value"></param>
        /// <param name="plus"></param>
        /// <returns></returns>
        public static byte[] FromDeciamlUInt32LittleEndian(this decimal value,decimal plus=1.0M)
        {
            var number=Convert.ToUInt32(value = value * plus);
            return number.FromUInt32LittleEndian();
        }
        /// <summary>
        /// 转换位无符号32位
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static uint ToUInt32BigEndian(this byte[] content)
        {
            return BitConverter.ToUInt32(content.Reverse().ToArray(),0);
        }
        /// <summary>
        /// 转换为ASCII码
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string ToASCII(this byte[] content)
        {
            return Encoding.ASCII.GetString(content);
        }
        /// <summary>
        /// 转换位32位decial数
        /// </summary>
        /// <param name="content"></param>
        /// <param name="percent"></param>
        /// <returns></returns>
        /// <exception cref="DivideByZeroException"></exception>
        public static decimal ToUInt32DecimalBigEndian(this byte[] content,decimal percent)
        {
            if (percent == 0)
            {
                throw new DivideByZeroException();
            }
           return content.ToUInt32BigEndian()/percent;
        }
        /// <summary>
        /// 转换位32位decimal数
        /// </summary>
        /// <param name="content"></param>
        /// <param name="percent"></param>
        /// <returns></returns>
        /// <exception cref="DivideByZeroException"></exception>
        public static decimal ToUInt32DecimalLittleEndian(this byte[] content, decimal percent)
        {
            if (percent == 0)
            {
                throw new DivideByZeroException();
            }
            return content.ToUInt32LittleEndian() / percent;
        }
        /// <summary>
        /// 转换位服务号16位
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static ushort ToUInt16LittleEndian(this byte[] content)
        {
            if (content.Length==0)
            {
                return 0;
            }
            return BitConverter.ToUInt16(content.ToArray(),0);
        }
        /// <summary>
        /// 转换位3字节24位整数
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static uint ToUInt24LittleEndian(this byte[] content)
        {
            List<byte> vs = new List<byte>();
            vs.AddRange(content);
            vs.Add(0);
            return BitConverter.ToUInt32(vs.ToArray(),0);
        }
        /// <summary>
        /// 转换位3字节24位整数 并转换为Decimal
        /// </summary>
        /// <param name="content"></param>
        /// <param name="percent"></param>
        /// <returns></returns>
        /// <exception cref="DivideByZeroException"></exception>
        public static decimal ToUInt24DecimalLittleEndian(this byte[] content, decimal percent)
        {
            if (percent == 0)
            {
                throw new DivideByZeroException();
            }
            return content.ToUInt24LittleEndian() / percent;
        }
        /// <summary>
        /// 转换位3字节24位整数 并转换为Decimal
        /// </summary>
        /// <param name="content"></param>
        /// <param name="percent"></param>
        /// <returns></returns>
        /// <exception cref="DivideByZeroException"></exception>
        public static decimal ToUInt24DecimalBigEndian(this byte[] content, decimal percent)
        {
            if (percent == 0)
            {
                throw new DivideByZeroException();
            }
            return content.ToUInt24BigEndian() / percent;
        }
        /// <summary>
        ///  转换位3字节24位整数
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static uint ToUInt24BigEndian(this byte[] content)
        {
            List<byte> vs = new List<byte>();
            vs.Add(0);
            vs.AddRange(content);
            return BitConverter.ToUInt32(vs.ToArray().Reverse().ToArray(),0);
        }
        /// <summary>
        /// 转换位32位数
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static uint ToUInt32LittleEndian(this byte[] content)
        {
            return BitConverter.ToUInt32(content.ToArray(),0);
        }
    }

}
